#include "Earth.hpp"
#include <iostream>
#include "SDL2/SDL_image.h"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include <sstream>
#include <iomanip>
#include "MathDefine.hpp"
#include "SDL2/SDL_ttf.h"

#include <filesystem>

_NNU_DGGS_BEGIN
namespace DGGSViewer
{
    // 顶点着色器
    auto vertexShaderSource = R"(
    #version 330 core
    layout (location = 0) in vec3 aPos;
    layout (location = 1) in vec2 aTexCoord;
    layout (location = 2) in vec3 aNormal;

    out vec2 TexCoord;
    out vec3 Normal;
    out vec3 FragPos;

    uniform mat4 model;
    uniform mat4 view;
    uniform mat4 projection;

    void main() {
        FragPos = vec3(model * vec4(aPos, 1.0));
        Normal = mat3(transpose(inverse(model))) * aNormal;
        TexCoord = aTexCoord;
        gl_Position = projection * view * model * vec4(aPos, 1.0);
    }
)";

    // 片段着色器
    auto fragmentShaderSource = R"(
    #version 330 core
    in vec2 TexCoord;
    in vec3 Normal;
    in vec3 FragPos;

    out vec4 FragColor;

    uniform sampler2D texture1;
    uniform vec3 lightPos;
    uniform vec3 viewPos;

    void main() {
        // 环境光
        float ambientStrength = 0.5;
        vec3 ambient = ambientStrength * vec3(1.0, 1.0, 1.0);

        // 漫反射
        vec3 norm = normalize(Normal);
        vec3 lightDir = normalize(lightPos - FragPos);
        float diff = max(dot(norm, lightDir), 0.0);
        vec3 diffuse = diff * vec3(1.0, 1.0, 1.0);

        // 高光
        float specularStrength = 0.2;
        vec3 viewDir = normalize(viewPos - FragPos);
        vec3 reflectDir = reflect(-lightDir, norm);
        float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
        vec3 specular = specularStrength * spec * vec3(1.0, 1.0, 1.0);

        vec4 texColor = texture(texture1, TexCoord);
        
        // 增强亮度和对比度
        vec3 color = texColor.rgb;
        float brightness = 1.2; // 增加亮度
        float contrast = 1.1; // 增加对比度
        
        // 应用亮度和对比度调整
        color = color * brightness;
        color = (color - 0.5) * contrast + 0.5;
        
        vec3 result = (ambient + diffuse + specular) * color;
        FragColor = vec4(result, 1.0);
    }
)";

    // 覆盖数据的顶点着色器
    auto overlayVertexShaderSource = R"(
    #version 330 core
    layout (location = 0) in vec3 aPos;
    layout (location = 1) in vec3 aColor;

    out vec3 Color;

    uniform mat4 model;
    uniform mat4 view;
    uniform mat4 projection;

    void main() {
        Color = aColor;
        gl_Position = projection * view * model * vec4(aPos, 1.0);
    }
)";

    // 覆盖数据的片段着色器
    auto overlayFragmentShaderSource = R"(
    #version 330 core
    in vec3 Color;
    
    out vec4 FragColor;
    
    uniform int geometryType; // 0=点, 1=线, 2=面
    uniform float overlayAlpha; // 全局透明度控制

    void main() {
        // 根据几何类型调整颜色和亮度
        vec3 brightColor = Color;
        float alpha = overlayAlpha; // 使用全局透明度
        
        if (geometryType == 0) { // 点
            // 点使用原始颜色加亮
            brightColor = Color * 1.5;
        } else if (geometryType == 1) { // 线
            // 线使用原始颜色加亮
            brightColor = Color * 1.5;
        } else { // 面
            // 面使用更加温和的颜色增强
            brightColor = Color * 1.2;
        }
        
        // 限制在[0,1]范围内
        brightColor = clamp(brightColor, 0.0, 1.0);
        
        FragColor = vec4(brightColor, alpha);
    }
)";

    // 快捷键说明的顶点着色器
    auto helpTextVertexShaderSource = R"(
    #version 330 core
    layout (location = 0) in vec2 aPos;
    layout (location = 1) in vec2 aTexCoord;

    out vec2 TexCoord;

    uniform mat4 projection;

    void main() {
        TexCoord = aTexCoord;
        gl_Position = projection * vec4(aPos, 0.0, 1.0);
    }
)";

    // 快捷键说明的片段着色器
    auto helpTextFragmentShaderSource = R"(
    #version 330 core
    in vec2 TexCoord;
    
    out vec4 FragColor;
    
    uniform sampler2D textTexture;

    void main() {
        FragColor = texture(textTexture, TexCoord);
    }
)";

    Earth::Earth()
        : m_vao(0),
          m_vbo(0),
          m_ebo(0),
          m_texture(0),
          m_shaderProgram(0),
          m_overlayShaderProgram(0),
          m_rotationAngle(0.0f),
          m_zoom(3.0f),
          m_rotationX(0.0f),
          m_rotationY(0.0f),
          m_autoRotate(true),
          m_overlayVBO(0),
          m_hasOverlayData(false),
          m_currentColorMap(ColorMapType::JET),
          m_dggsVisualizer(nullptr),
          m_showCoordinateLabel(false),
          m_windowWidth(800),
          m_windowHeight(600),
          m_overlayAlpha(0.8f),
          m_showHelpText(true),
          m_helpTextVAO(0),
          m_helpTextVBO(0),
          m_helpTextShaderProgram(0),
          m_font(nullptr),
          m_helpPanelTexture(0),
          m_helpPanelNeedsUpdate(true),
          m_panelVAO(0),
          m_panelVBO(0),
          m_panelEBO(0),
          m_showGrid(true),
          m_gridVAO(0),
          m_gridVBO(0),
          m_lastGridZoom(3.0f),
          m_gridZoomThreshold(0.5f),
          m_showGridLabels(true),
          m_labelTextureAtlas(0)
    {
        // 初始化选中的经纬度为无效值
        m_selectedCoordinate = {0.0, 0.0, false};
    }

    Earth::~Earth()
    {
        glDeleteVertexArrays(1, &m_vao);
        glDeleteBuffers(1, &m_vbo);
        glDeleteBuffers(1, &m_ebo);
        glDeleteTextures(1, &m_texture);
        glDeleteProgram(m_shaderProgram);
        
        if (m_helpTextVAO != 0)
        {
            glDeleteVertexArrays(1, &m_helpTextVAO);
        }
        
        if (m_helpTextVBO != 0)
        {
            glDeleteBuffers(1, &m_helpTextVBO);
        }
        
        if (m_helpTextShaderProgram != 0)
        {
            glDeleteProgram(m_helpTextShaderProgram);
        }
        
        // 清理面板相关资源
        if (m_panelVAO != 0)
        {
            glDeleteVertexArrays(1, &m_panelVAO);
        }
        
        if (m_panelVBO != 0)
        {
            glDeleteBuffers(1, &m_panelVBO);
        }
        
        if (m_panelEBO != 0)
        {
            glDeleteBuffers(1, &m_panelEBO);
        }
        
        // 删除帮助面板纹理
        if (m_helpPanelTexture != 0)
        {
            glDeleteTextures(1, &m_helpPanelTexture);
        }
        
        // 关闭字体
        if (m_font != nullptr)
        {
            TTF_CloseFont(m_font);
            m_font = nullptr;
        }
        
        // 关闭TTF库
        TTF_Quit();

        if (m_hasOverlayData)
        {
            glDeleteBuffers(1, &m_overlayVBO);
        }
        
        // 清理经纬网资源
        if (m_gridVAO != 0)
        {
            glDeleteVertexArrays(1, &m_gridVAO);
        }
        
        if (m_gridVBO != 0)
        {
            glDeleteBuffers(1, &m_gridVBO);
        }
        
        // 清理经纬网标注纹理
        if (m_labelTextureAtlas != 0)
        {
            glDeleteTextures(1, &m_labelTextureAtlas);
        }
    }

    bool Earth::initialize()
    {
        // 初始化GLEW
        GLenum err = glewInit();
        if (err != GLEW_OK)
        {
            std::cerr << "GLEW初始化失败: " << glewGetErrorString(err) << std::endl;
            return false;
        }

        std::cout << "GLEW初始化成功" << std::endl;

        // 编译地球着色器
        GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
        glCompileShader(vertexShader);

        // 检查顶点着色器编译错误
        int success;
        char infoLog[512];
        glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);
            std::cerr << "顶点着色器编译失败: " << infoLog << std::endl;
            return false;
        }

        std::cout << "顶点着色器编译成功" << std::endl;

        // 编译片段着色器
        GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
        glCompileShader(fragmentShader);

        // 检查片段着色器编译错误
        glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(fragmentShader, 512, nullptr, infoLog);
            std::cerr << "片段着色器编译失败: " << infoLog << std::endl;
            return false;
        }

        // 链接地球着色器程序
        m_shaderProgram = glCreateProgram();
        glAttachShader(m_shaderProgram, vertexShader);
        glAttachShader(m_shaderProgram, fragmentShader);
        glLinkProgram(m_shaderProgram);

        // 检查链接错误
        glGetProgramiv(m_shaderProgram, GL_LINK_STATUS, &success);
        if (!success)
        {
            glGetProgramInfoLog(m_shaderProgram, 512, nullptr, infoLog);
            std::cerr << "着色器程序链接失败: " << infoLog << std::endl;
            return false;
        }

        // 清理地球着色器
        glDeleteShader(vertexShader);
        glDeleteShader(fragmentShader);

        // 编译覆盖数据着色器
        GLuint overlayVertexShader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(overlayVertexShader, 1, &overlayVertexShaderSource, nullptr);
        glCompileShader(overlayVertexShader);

        // 检查覆盖顶点着色器编译错误
        glGetShaderiv(overlayVertexShader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(overlayVertexShader, 512, nullptr, infoLog);
            std::cerr << "覆盖顶点着色器编译失败: " << infoLog << std::endl;
            return false;
        }

        // 编译覆盖片段着色器
        GLuint overlayFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(overlayFragmentShader, 1, &overlayFragmentShaderSource, nullptr);
        glCompileShader(overlayFragmentShader);

        // 检查覆盖片段着色器编译错误
        glGetShaderiv(overlayFragmentShader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(overlayFragmentShader, 512, nullptr, infoLog);
            std::cerr << "覆盖片段着色器编译失败: " << infoLog << std::endl;
            return false;
        }

        // 链接覆盖着色器程序
        m_overlayShaderProgram = glCreateProgram();
        glAttachShader(m_overlayShaderProgram, overlayVertexShader);
        glAttachShader(m_overlayShaderProgram, overlayFragmentShader);
        glLinkProgram(m_overlayShaderProgram);

        // 检查覆盖着色器链接错误
        glGetProgramiv(m_overlayShaderProgram, GL_LINK_STATUS, &success);
        if (!success)
        {
            glGetProgramInfoLog(m_overlayShaderProgram, 512, nullptr, infoLog);
            std::cerr << "覆盖着色器程序链接失败: " << infoLog << std::endl;
            return false;
        }

        // 清理覆盖着色器
        glDeleteShader(overlayVertexShader);
        glDeleteShader(overlayFragmentShader);

        // 编译快捷键说明着色器
        GLuint helpTextVertexShader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(helpTextVertexShader, 1, &helpTextVertexShaderSource, nullptr);
        glCompileShader(helpTextVertexShader);

        // 检查快捷键说明顶点着色器编译错误
        glGetShaderiv(helpTextVertexShader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(helpTextVertexShader, 512, nullptr, infoLog);
            std::cerr << "快捷键说明顶点着色器编译失败: " << infoLog << std::endl;
            return false;
        }

        // 编译快捷键说明片段着色器
        GLuint helpTextFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(helpTextFragmentShader, 1, &helpTextFragmentShaderSource, nullptr);
        glCompileShader(helpTextFragmentShader);

        // 检查快捷键说明片段着色器编译错误
        glGetShaderiv(helpTextFragmentShader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(helpTextFragmentShader, 512, nullptr, infoLog);
            std::cerr << "快捷键说明片段着色器编译失败: " << infoLog << std::endl;
            return false;
        }

        // 链接快捷键说明着色器程序
        m_helpTextShaderProgram = glCreateProgram();
        glAttachShader(m_helpTextShaderProgram, helpTextVertexShader);
        glAttachShader(m_helpTextShaderProgram, helpTextFragmentShader);
        glLinkProgram(m_helpTextShaderProgram);

        // 检查快捷键说明着色器链接错误
        glGetProgramiv(m_helpTextShaderProgram, GL_LINK_STATUS, &success);
        if (!success)
        {
            glGetProgramInfoLog(m_helpTextShaderProgram, 512, nullptr, infoLog);
            std::cerr << "快捷键说明着色器程序链接失败: " << infoLog << std::endl;
            return false;
        }

        // 清理快捷键说明着色器
        glDeleteShader(helpTextVertexShader);
        glDeleteShader(helpTextFragmentShader);

        // 创建球体
        createSphere(1.0f, 32, 32);

        // 创建VAO、VBO和EBO
        glGenVertexArrays(1, &m_vao);
        glGenBuffers(1, &m_vbo);
        glGenBuffers(1, &m_ebo);

        glBindVertexArray(m_vao);

        glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
        glBufferData(GL_ARRAY_BUFFER, m_vertices.size() * sizeof(float), m_vertices.data(), GL_STATIC_DRAW);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indices.size() * sizeof(unsigned int), m_indices.data(),
                     GL_STATIC_DRAW);

        // 位置属性
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), static_cast<void*>(nullptr));
        glEnableVertexAttribArray(0);

        // 纹理坐标属性
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), reinterpret_cast<void*>(3 * sizeof(float)));
        glEnableVertexAttribArray(1);

        // 法线属性
        glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), reinterpret_cast<void*>(5 * sizeof(float)));
        glEnableVertexAttribArray(2);

        // 初始化帮助面板VAO、VBO和EBO
        glGenVertexArrays(1, &m_panelVAO);
        glGenBuffers(1, &m_panelVBO);
        glGenBuffers(1, &m_panelEBO);
        
        // 初始化面板顶点数据
        float panelVertices[] = {
            // 位置(x,y)           纹理坐标(s,t)
            0.0f, 1.0f,            0.0f, 0.0f,  // 左上
            0.0f, 0.0f,            0.0f, 1.0f,  // 左下
            1.0f, 0.0f,            1.0f, 1.0f,  // 右下
            1.0f, 1.0f,            1.0f, 0.0f   // 右上
        };
        
        // 索引数据，两个三角形组成一个矩形
        unsigned int indices[] = {
            0, 1, 2,  // 第一个三角形
            0, 2, 3   // 第二个三角形
        };
        
        // 绑定和设置
        glBindVertexArray(m_panelVAO);
        
        glBindBuffer(GL_ARRAY_BUFFER, m_panelVBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(panelVertices), panelVertices, GL_STATIC_DRAW);
        
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_panelEBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
        
        // 位置属性
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(0);
        
        // 纹理坐标属性
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
        glEnableVertexAttribArray(1);
        
        glBindVertexArray(0);
        
        // 初始化TTF
        if (!initTTF())
        {
            std::cerr << "TTF初始化失败，将使用基本图形显示快捷键说明" << std::endl;
            // 失败不终止程序，会降级为使用基本图形渲染
        }
        
        if (err != GL_NO_ERROR)
        {
            std::cerr << "OpenGL错误(TTF初始化后): " << err << std::endl;
        }

        // 加载地球纹理
        auto textureFileName = std::filesystem::current_path().string()+"/"+"earth.jpg";
        if (!loadTexture(textureFileName.c_str()))
        {
            std::cerr << "地球纹理加载失败" << std::endl;
            return false;
        }

        // 设置投影矩阵 - 使用默认值，稍后会在updateProjection中更新
        updateProjection(800, 600);

        // 设置视图矩阵
        m_viewMatrix = glm::lookAt(
            glm::vec3(0.0f, 0.0f, 3.0f), // 相机位置
            glm::vec3(0.0f, 0.0f, 0.0f), // 目标位置
            glm::vec3(0.0f, 1.0f, 0.0f) // 上向量
        );

        // 启用深度测试
        glEnable(GL_DEPTH_TEST);
        
        // 创建经纬网
        createGrid();

        return true;
    }

    void Earth::render()
    {
        // 如果自动旋转启用，更新旋转角度
        if (m_autoRotate)
        {
            m_rotationAngle += 0.1f;
        }

        // 更新模型矩阵
        m_modelMatrix = glm::mat4(1.0f);
        m_modelMatrix = glm::rotate(m_modelMatrix, glm::radians(m_rotationX), glm::vec3(1.0f, 0.0f, 0.0f));
        m_modelMatrix = glm::rotate(m_modelMatrix, glm::radians(m_rotationY), glm::vec3(0.0f, 1.0f, 0.0f));

        // 更新视图矩阵
        m_viewMatrix = glm::lookAt(
            glm::vec3(0.0f, 0.0f, m_zoom), // 相机位置，使用缩放值
            glm::vec3(0.0f, 0.0f, 0.0f), // 目标位置
            glm::vec3(0.0f, 1.0f, 0.0f) // 上向量
        );

        // 检查是否需要更新经纬网
        if (m_showGrid && needGridUpdate())
        {
            createGrid(); // 更新经纬网
        }

        // 获取当前OpenGL错误
        GLenum err = glGetError();
        if (err != GL_NO_ERROR)
        {
            std::cerr << "OpenGL错误(渲染前): " << err << std::endl;
        }

        // 绘制地球
        renderEarth();

        // 如果启用了经纬网，绘制它
        if (m_showGrid)
        {
            renderGrid();
        }

        // 如果启用了经纬网标注，绘制它
        if (m_showGrid && m_showGridLabels)
        {
            // 获取当前缩放级别的经纬度间隔
            float longitudeStep = getLongitudeStep(m_zoom);
            float latitudeStep = getLatitudeStep(m_zoom);
            
            renderGridLabels(longitudeStep, latitudeStep);
        }

        // 如果有覆盖数据，绘制它
        if (m_hasOverlayData)
        {
            renderOverlayData();
        }

        // 如果有选中的有效经纬度，绘制标识
        if (m_showCoordinateLabel && m_selectedCoordinate.isValid)
        {
            renderCoordinateLabel();
        }
        
        // 如果启用了快捷键说明，绘制它
        if (m_showHelpText)
        {
            renderHelpText();
        }

        // 检查渲染后的错误
        err = glGetError();
        if (err != GL_NO_ERROR)
        {
            std::cerr << "OpenGL错误(渲染后): " << err << std::endl;
        }
    }

    void Earth::renderEarth()
    {
        // 不再需要在这里再次设置状态，因为render方法已经设置好了
        // 使用着色器程序
        glUseProgram(m_shaderProgram);

        // 设置矩阵
        GLint modelLoc = glGetUniformLocation(m_shaderProgram, "model");
        GLint viewLoc = glGetUniformLocation(m_shaderProgram, "view");
        GLint projectionLoc = glGetUniformLocation(m_shaderProgram, "projection");

        glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(m_modelMatrix));
        glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(m_viewMatrix));
        glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(m_projectionMatrix));

        // 设置光源位置
        GLint lightPosLoc = glGetUniformLocation(m_shaderProgram, "lightPos");
        glUniform3f(lightPosLoc, 2.0f, 2.0f, 2.0f);

        // 设置视点位置
        GLint viewPosLoc = glGetUniformLocation(m_shaderProgram, "viewPos");
        glUniform3f(viewPosLoc, 0.0f, 0.0f, m_zoom);

        // 绑定纹理
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, m_texture);

        // 检查纹理
        if (m_texture == 0)
        {
            std::cerr << "错误：纹理未加载" << std::endl;
        }

        // 检查VAO和绘制调用
        if (m_vao == 0)
        {
            std::cerr << "错误：VAO未创建" << std::endl;
        }
        else
        {
            // 绘制地球
            glBindVertexArray(m_vao);

            // 确保索引已正确加载
            if (m_indices.empty())
            {
                std::cerr << "错误：索引数组为空" << std::endl;
            }
            else
            {
                glDrawElements(GL_TRIANGLES, m_indices.size(), GL_UNSIGNED_INT, nullptr);
            }

            // 重置顶点数组绑定
            glBindVertexArray(0);
        }

        glUseProgram(0);

        // 检查渲染中的错误
        GLenum err = glGetError();
        if (err != GL_NO_ERROR)
        {
            std::cerr << "OpenGL错误(地球渲染中): " << err << std::endl;
        }
    }

    void Earth::renderOverlayData()
    {
        if (!m_hasOverlayData || m_overlayData.empty() || m_overlayVBO == 0)
        {
            return;
        }

        // 创建一个VAO用于覆盖数据的渲染，如果还没有创建的话
        static GLuint overlayVAO = 0;
        if (overlayVAO == 0)
        {
            glGenVertexArrays(1, &overlayVAO);
        }

        // 保存当前OpenGL状态
        GLboolean depthMaskEnabled;
        glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMaskEnabled);

        // 设置混合
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        // 设置深度测试 - 关键是不写入深度但仍进行深度测试
        glDepthMask(GL_FALSE); // 禁用深度写入，这样覆盖数据不会影响地球的深度

        // 启用多边形偏移以避免z-fighting
        glEnable(GL_POLYGON_OFFSET_FILL);
        glPolygonOffset(-0.5f, -0.5f);

        // 使用覆盖数据着色器
        glUseProgram(m_overlayShaderProgram);

        // 设置矩阵
        GLint modelLoc = glGetUniformLocation(m_overlayShaderProgram, "model");
        GLint viewLoc = glGetUniformLocation(m_overlayShaderProgram, "view");
        GLint projectionLoc = glGetUniformLocation(m_overlayShaderProgram, "projection");

        glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(m_modelMatrix));
        glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(m_viewMatrix));
        glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(m_projectionMatrix));

        // 设置几何类型uniform
        GLint geometryTypeLoc = glGetUniformLocation(m_overlayShaderProgram, "geometryType");
        int geometryType = 0; // 默认为点

        // 设置透明度uniform
        GLint alphaLoc = glGetUniformLocation(m_overlayShaderProgram, "overlayAlpha");
        glUniform1f(alphaLoc, m_overlayAlpha);

        if (m_dggsVisualizer)
        {
            switch (m_dggsVisualizer->type)
            {
            case DGGSElementType::Vertex: geometryType = 0;
                break;
            case DGGSElementType::Edge: geometryType = 1;
                break;
            case DGGSElementType::Cell: geometryType = 2;
                break;
            default: geometryType = 0;
                break;
            }
        }

        glUniform1i(geometryTypeLoc, geometryType);

        // 绑定并设置VAO
        glBindVertexArray(overlayVAO);
        glBindBuffer(GL_ARRAY_BUFFER, m_overlayVBO);

        // 设置顶点和颜色属性
        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), static_cast<void*>(nullptr));
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), reinterpret_cast<void*>(3 * sizeof(float)));

        // 根据几何类型选择绘制方式
        if (m_dggsVisualizer)
        {
            switch (m_dggsVisualizer->type)
            {
            case DGGSElementType::Vertex:
                glPointSize(10.0f); // 使点更大
                glDrawArrays(GL_POINTS, 0, m_overlayData.size() / 6);
                break;

            case DGGSElementType::Edge:
                glLineWidth(4.0f); // 使线更粗
                glDrawArrays(GL_LINES, 0, m_overlayData.size() / 6);
                break;

            case DGGSElementType::Cell:
                glDrawArrays(GL_TRIANGLES, 0, m_overlayData.size() / 6);
                break;

            default:
                glPointSize(8.0f);
                glDrawArrays(GL_POINTS, 0, m_overlayData.size() / 6);
                break;
            }
        }

        // 恢复OpenGL状态
        glDisable(GL_POLYGON_OFFSET_FILL);
        glDepthMask(depthMaskEnabled);
        glDisable(GL_BLEND);

        // 重置绑定
        glBindVertexArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glUseProgram(0);
    }

    void Earth::loadData(const std::string& filePath)
    {
        std::cout << "加载数据文件: " << filePath << std::endl;

        delete m_dggsVisualizer;

        m_dggsVisualizer = new DGGSVisualizer();
        m_dggsVisualizer->loadData(filePath);

        // 打印加载的数据信息
        if (m_dggsVisualizer && !m_dggsVisualizer->cells.empty())
        {
            std::cout << "数据加载成功，单元数量: " << m_dggsVisualizer->cells.size() << std::endl;

            std::string typeStr;
            switch (m_dggsVisualizer->type)
            {
            case DGGSElementType::Vertex:
                typeStr = "点";
                break;
            case DGGSElementType::Edge:
                typeStr = "线";
                break;
            case DGGSElementType::Cell:
                typeStr = "面";
                break;
            default:
                typeStr = "未知";
                break;
            }

            std::cout << "几何类型: " << typeStr << std::endl;

            if (!m_dggsVisualizer->cells.empty())
            {
                const size_t bandCount = m_dggsVisualizer->cells[0].values.size();
                std::cout << "波段数: " << bandCount << std::endl;
            }
        }
        else
        {
            std::cout << "数据加载失败或没有单元" << std::endl;
        }

        // 生成覆盖数据
        generateOverlayData();
    }

    void Earth::loadMultipleData(const std::vector<std::string>& filePaths)
    {
        if (filePaths.empty())
        {
            std::cout << "没有选择任何文件" << std::endl;
            return;
        }

        std::cout << "加载多个数据文件, 文件数量: " << filePaths.size() << std::endl;

        delete m_dggsVisualizer;

        m_dggsVisualizer = new DGGSVisualizer();

        m_dggsVisualizer->loadMultipleData(filePaths);

        // 打印加载的数据信息
        if (m_dggsVisualizer && !m_dggsVisualizer->cells.empty())
        {
            std::cout << "数据加载成功，单元数量: " << m_dggsVisualizer->cells.size() << std::endl;

            std::string typeStr;
            switch (m_dggsVisualizer->type)
            {
            case DGGSElementType::Vertex:
                typeStr = "点";
                break;
            case DGGSElementType::Edge:
                typeStr = "线";
                break;
            case DGGSElementType::Cell:
                typeStr = "面";
                break;
            default:
                typeStr = "未知";
                break;
            }

            std::cout << "几何类型: " << typeStr << std::endl;

            if (!m_dggsVisualizer->cells.empty())
            {
                const size_t bandCount = m_dggsVisualizer->cells[0].values.size();
                std::cout << "波段数: " << bandCount << std::endl;
            }
        }
        else
        {
            std::cout << "数据加载失败或没有单元" << std::endl;
        }

        // 生成覆盖数据
        generateOverlayData();
    }

    bool Earth::loadTexture(const std::string& texturePath)
    {
        // 使用SDL_image加载纹理
        SDL_Surface* surface = IMG_Load(texturePath.c_str());
        if (!surface)
        {
            std::cerr << "无法加载图像 " << texturePath << ": " << IMG_GetError() << std::endl;

            // 创建一个简单的棋盘格纹理作为替代
            surface = SDL_CreateRGBSurface(0, 256, 128, 32, 0, 0, 0, 0);
            if (!surface)
            {
                std::cerr << "无法创建替代表面: " << SDL_GetError() << std::endl;
                return false;
            }

            // 绘制棋盘格
            SDL_Rect rect;
            rect.w = 32;
            rect.h = 32;

            for (int y = 0; y < 4; y++)
            {
                for (int x = 0; x < 8; x++)
                {
                    rect.x = x * 32;
                    rect.y = y * 32;

                    Uint32 color = ((x + y) % 2)
                                       ? SDL_MapRGB(surface->format, 0, 0, 128)
                                       : SDL_MapRGB(surface->format, 0, 128, 255);

                    SDL_FillRect(surface, &rect, color);
                }
            }
        }

        // 创建OpenGL纹理
        glGenTextures(1, &m_texture);
        glBindTexture(GL_TEXTURE_2D, m_texture);

        // 设置纹理参数
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        // 确定格式
        GLenum format;
        if (surface->format->BytesPerPixel == 4)
        {
            format = (surface->format->Rmask == 0x000000ff) ? GL_RGBA : GL_BGRA;
        }
        else
        {
            format = (surface->format->Rmask == 0x000000ff) ? GL_RGB : GL_BGR;
        }

        // 加载纹理数据
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, surface->w, surface->h, 0, format, GL_UNSIGNED_BYTE, surface->pixels);
        glGenerateMipmap(GL_TEXTURE_2D);

        // 释放表面
        SDL_FreeSurface(surface);

        return true;
    }

    // 辅助方法：调整贴图以匹配坐标系
    void Earth::createSphere(float radius, unsigned int rings, unsigned int sectors)
    {
        m_vertices.clear();
        m_indices.clear();

        std::cout << "开始生成球体，半径: " << radius << "，rings: " << rings << "，sectors: " << sectors << std::endl;

        float const R = 1.0f / static_cast<float>(rings - 1);
        float const S = 1.0f / static_cast<float>(sectors - 1);

        // 计算地球的缩放因子，确保与覆盖数据使用相同的缩放
        float scaleFactor = 1.0f / static_cast<float>(earthRadius);
        std::cout << "球体缩放因子: " << scaleFactor << std::endl;

        // 使用经纬度和LLE2XYZ生成球体
        for (unsigned int r = 0; r < rings; ++r)
        {
            // 纬度从-90度到90度
            double lat = -90.0 + 180.0 * r * R;

            for (unsigned int s = 0; s < sectors; ++s)
            {
                // 经度从-180度到180度
                double lon = -180.0 + 360.0 * s * S;

                // 使用LLE2XYZ函数将经纬度坐标转换为3D笛卡尔坐标
                long double x, y, z;
                // 由于LLE2XYZ会使用earthRadius，我们需要先获取单位向量
                LLE2XYZ(lon, lat, 0.0, x, y, z);

                // 应用缩放因子和指定半径
                x *= scaleFactor * radius;
                y *= scaleFactor * radius;
                z *= scaleFactor * radius;

                // 将坐标转换为OpenGL坐标系
                float openglX = static_cast<float>(x);
                float openglY = static_cast<float>(z); // MathDefine的z对应OpenGL的y
                float openglZ = static_cast<float>(-y); // MathDefine的y对应OpenGL的z，取反修复方向

                // 法线 = 单位方向向量
                float nx = openglX / radius;
                float ny = openglY / radius;
                float nz = openglZ / radius;

                // 纹理坐标 - 根据经纬度直接映射
                float const u = s * S; // 经度从左到右：0->1对应-180度到180度
                float const v = 1.0f - r * R; // 纬度从上到下：1->0对应90度到-90度

                // 顶点数据：位置(x,y,z)，纹理坐标(u,v)，法线(x,y,z)
                m_vertices.push_back(openglX);
                m_vertices.push_back(openglY);
                m_vertices.push_back(openglZ);
                m_vertices.push_back(u);
                m_vertices.push_back(v);
                m_vertices.push_back(nx);
                m_vertices.push_back(ny);
                m_vertices.push_back(nz);
            }
        }

        // 生成索引
        for (unsigned int r = 0; r < rings - 1; ++r)
        {
            for (unsigned int s = 0; s < sectors - 1; ++s)
            {
                unsigned int const i1 = r * sectors + s;
                unsigned int const i2 = r * sectors + (s + 1);
                unsigned int const i3 = (r + 1) * sectors + (s + 1);
                unsigned int const i4 = (r + 1) * sectors + s;

                // 两个三角形
                m_indices.push_back(i1);
                m_indices.push_back(i2);
                m_indices.push_back(i4);

                m_indices.push_back(i2);
                m_indices.push_back(i3);
                m_indices.push_back(i4);
            }
        }

        std::cout << "球体生成完成，顶点数: " << m_vertices.size() / 8 << "，三角形数: " << m_indices.size() / 3 << std::endl;
    }

    void Earth::handleMouseWheel(float yOffset)
    {
        // 缩放因子
        float zoomFactor = 0.05f;

        // 更新缩放值
        m_zoom -= yOffset * zoomFactor;
        
        // 限制缩放范围
        if (m_zoom < 1.0f)
        {
            m_zoom = 1.0f;
        }
        else if (m_zoom > 10.0f)
        {
            m_zoom = 10.0f;
        }
    }

    void Earth::handleMouseDrag(int xRel, int yRel, bool isLeftButton)
    {
        if (isLeftButton)
        {
            // 旋转因子
            float rotationFactor = 0.5f;

            // 更新旋转值
            m_rotationY += xRel * rotationFactor;
            m_rotationX += yRel * rotationFactor;

            // 限制X轴旋转范围，防止翻转
            if (m_rotationX > 89.0f)
            {
                m_rotationX = 89.0f;
            }
            else if (m_rotationX < -89.0f)
            {
                m_rotationX = -89.0f;
            }

            // 当用户拖动时，禁用自动旋转
            m_autoRotate = false;
        }
    }

    void Earth::resetView()
    {
        m_zoom = 3.0f;
        m_rotationX = 0.0f;
        m_rotationY = 0.0f;
        m_autoRotate = true;
    }

    void Earth::updateProjection(int windowWidth, int windowHeight)
    {
        // 更新投影矩阵，保持宽高比
        float aspectRatio = static_cast<float>(windowWidth) / static_cast<float>(windowHeight);
        m_projectionMatrix = glm::perspective(glm::radians(45.0f), aspectRatio, 0.1f, 100.0f);

        // 设置视口大小
        glViewport(0, 0, windowWidth, windowHeight);

        // 保存窗口尺寸
        m_windowWidth = windowWidth;
        m_windowHeight = windowHeight;
    }

    void Earth::handleKeyboard(SDL_Keycode key)
    {
        switch (key)
        {
        case SDLK_1:
            m_currentColorMap = ColorMapType::RGB;
            break;
        case SDLK_2:
            m_currentColorMap = ColorMapType::JET;
            break;
        case SDLK_3:
            m_currentColorMap = ColorMapType::VIRIDIS;
            break;
        case SDLK_4:
            m_currentColorMap = ColorMapType::PLASMA;
            break;
        case SDLK_5:
            m_currentColorMap = ColorMapType::INFERNO;
            break;
        case SDLK_6:
            m_currentColorMap = ColorMapType::MAGMA;
            break;
        case SDLK_7:
            m_currentColorMap = ColorMapType::GRAYSCALE;
            break;
        case SDLK_g:
            // 切换经纬网显示状态
            toggleGrid();
            break;
        case SDLK_l:
            // 切换经纬网标注显示状态
            toggleGridLabels();
            break;
        case SDLK_UP:
            // 增加透明度
            adjustOverlayAlpha(0.05f);
            break;
        case SDLK_DOWN:
            // 减少透明度
            adjustOverlayAlpha(-0.05f);
            break;
        default:
            return;
        }

        // 重新生成覆盖数据以应用新的色带
        if ((key >= SDLK_1 && key <= SDLK_7) && m_dggsVisualizer && !m_dggsVisualizer->cells.empty())
        {
            generateOverlayData();
        }
    }

    glm::vec3 Earth::applyColorMap(float value, ColorMapType colorMapType)
    {
        // 确保值在[0,1]范围内
        float v = std::max(0.0f, std::min(1.0f, value));

        switch (colorMapType)
        {
        case ColorMapType::RGB:
            // 多波段数据会使用另一种方式处理，这里返回红色
            return glm::vec3(v, 0.0f, 0.0f);

        case ColorMapType::JET:
            // Jet色带: 蓝->青->绿->黄->红
            if (v < 0.125f)
            {
                return glm::vec3(0.0f, 0.0f, 0.5f + 4.0f * v);
            }
            else if (v < 0.375f)
            {
                return glm::vec3(0.0f, 4.0f * (v - 0.125f), 1.0f);
            }
            else if (v < 0.625f)
            {
                return glm::vec3(4.0f * (v - 0.375f), 1.0f, 1.0f - 4.0f * (v - 0.375f));
            }
            else if (v < 0.875f)
            {
                return glm::vec3(1.0f, 1.0f - 4.0f * (v - 0.625f), 0.0f);
            }
            else
            {
                return glm::vec3(1.0f - 4.0f * (v - 0.875f), 0.0f, 0.0f);
            }

        case ColorMapType::VIRIDIS:
            // 简化的Viridis色带
            return glm::vec3(
                0.267f + 0.624f * v,
                0.0049f + 0.714f * v - 0.723f * v * v,
                0.329f + 0.532f * (1.0f - v)
            );

        case ColorMapType::PLASMA:
            // 简化的Plasma色带
            return glm::vec3(
                0.05f + 1.0f * v,
                0.03f + 0.81f * v - 0.82f * v * v,
                0.52f - 0.46f * v
            );

        case ColorMapType::INFERNO:
            // 简化的Inferno色带
            return {
                0.001f + 1.32f * v - 0.33f * v * v,
                0.0f + 0.55f * v * v,
                0.042f + 0.09f * v - 0.11f * v * v
            };

        case ColorMapType::MAGMA:
            // 简化的Magma色带
            return {
                0.001f + 1.25f * v - 0.25f * v * v,
                0.07f * v + 0.93f * v * v - 0.97f * v * v * v,
                0.234f + 0.352f * v - 0.584f * v * v
            };

        case ColorMapType::GRAYSCALE:
            // 灰度色带
            return {v, v, v};

        default:
            return glm::vec3(v, v, v);
        }
    }

    void Earth::generateOverlayData()
    {
        if (!m_dggsVisualizer || m_dggsVisualizer->cells.empty())
        {
            m_hasOverlayData = false;
            std::cout << "无法生成覆盖数据：可视化器为空或无单元" << std::endl;
            return;
        }

        std::cout << "单元数量: " << m_dggsVisualizer->cells.size() << std::endl;

        // 清空旧数据
        m_overlayData.clear();
        const auto& cells = m_dggsVisualizer->cells;
        const auto elementType = m_dggsVisualizer->type;

        // 打印几何类型信息
        std::string typeString;
        switch (elementType)
        {
        case DGGSElementType::Vertex: typeString = "点";
            break;
        case DGGSElementType::Edge: typeString = "线";
            break;
        case DGGSElementType::Cell: typeString = "面";
            break;
        default: typeString = "未知";
            break;
        }
        std::cout << "几何类型: " << typeString << std::endl;

        // 查找最小值和最大值以进行归一化
        double minValue = std::numeric_limits<double>::max();
        double maxValue = std::numeric_limits<double>::lowest();

        // 打印波段数
        size_t bandCount = 0;
        if (!cells.empty() && !cells[0].values.empty())
        {
            bandCount = cells[0].values.size();
            std::cout << "波段数: " << bandCount << std::endl;
        }
        else
        {
            std::cout << "无波段数据" << std::endl;
        }

        // 只在需要归一化时计算最小最大值
        const bool needNormalize = (m_currentColorMap != ColorMapType::RGB || bandCount == 1);

        if (needNormalize)
        {
            for (const auto& cell : cells)
            {
                // 如果是单波段，使用第一个波段值
                if (!cell.values.empty())
                {
                    minValue = std::min(minValue, cell.values[0]);
                    maxValue = std::max(maxValue, cell.values[0]);
                }
            }
        }

        // 避免除零错误
        if (std::abs(maxValue - minValue) < 1e-6)
        {
            maxValue = minValue + 1.0;
        }

        // 定义地球半径和偏移量
        // 地球模型半径为1.0，因此覆盖数据略大一些，确保它们显示在地球表面上方
        const float offsetRadius = 1.0001f; // 微小偏移，接近地球表面

        // 计算归一化因子 - 将地球真实半径映射到渲染半径1.0
        float scaleFactor = 1.0f / static_cast<float>(earthRadius);

        size_t processedCells = 0;
        size_t skippedCells = 0;

        // 生成几何图形数据
        for (const auto& cell : cells)
        {
            if (elementType == DGGSElementType::Vertex)
            {
                // 处理点数据
                if (!cell.m_coordinates.empty())
                {
                    processedCells++;
                    // 转换经纬度坐标为3D坐标
                    const auto& geo = cell.m_coordinates[0];

                    // 使用LLE2XYZ将经纬度转换为3D坐标
                    long double llx, lly, llz;
                    LLE2XYZ(geo.lon, geo.lat, 0.0, llx, lly, llz);

                    // 转换坐标系：MathDefine到OpenGL，并应用归一化
                    float x = static_cast<float>(llx) * scaleFactor * offsetRadius;
                    float y = static_cast<float>(llz) * scaleFactor * offsetRadius; // MathDefine的z对应OpenGL的y
                    float z = static_cast<float>(-lly) * scaleFactor * offsetRadius; // MathDefine的y对应OpenGL的z，取反修复方向

                    // 计算颜色
                    glm::vec3 color(1.0f, 0.0f, 0.0f); // 默认红色

                    if (m_currentColorMap == ColorMapType::RGB && cell.values.size() >= 3)
                    {
                        // 多波段数据直接映射为RGB
                        color.r = static_cast<float>(std::min(255.0, std::max(0.0, cell.values[0])) / 255.0);
                        color.g = static_cast<float>(std::min(255.0, std::max(0.0, cell.values[1])) / 255.0);
                        color.b = static_cast<float>(std::min(255.0, std::max(0.0, cell.values[2])) / 255.0);
                    }
                    else if (!cell.values.empty())
                    {
                        // 单波段数据使用色带
                        const float normalizedValue = static_cast<float>((cell.values[0] - minValue) / (maxValue -
                            minValue));
                        color = applyColorMap(normalizedValue, m_currentColorMap);
                    }

                    // 添加顶点和颜色数据
                    m_overlayData.push_back(x);
                    m_overlayData.push_back(y);
                    m_overlayData.push_back(z);
                    m_overlayData.push_back(color.r);
                    m_overlayData.push_back(color.g);
                    m_overlayData.push_back(color.b);
                }
                else
                {
                    skippedCells++;
                }
            }
            else if (elementType == DGGSElementType::Edge)
            {
                // 处理线数据
                if (cell.m_coordinates.size() >= 2)
                {
                    processedCells++;

                    // 计算颜色
                    glm::vec3 color(0.0f, 1.0f, 0.0f); // 默认绿色

                    if (m_currentColorMap == ColorMapType::RGB && cell.values.size() >= 3)
                    {
                        // 多波段数据直接映射为RGB
                        color.r = static_cast<float>(std::min(255.0, std::max(0.0, cell.values[0])) / 255.0);
                        color.g = static_cast<float>(std::min(255.0, std::max(0.0, cell.values[1])) / 255.0);
                        color.b = static_cast<float>(std::min(255.0, std::max(0.0, cell.values[2])) / 255.0);
                    }
                    else if (!cell.values.empty())
                    {
                        // 单波段数据使用色带
                        const float normalizedValue = static_cast<float>((cell.values[0] - minValue) / (maxValue -
                            minValue));
                        color = applyColorMap(normalizedValue, m_currentColorMap);
                    }

                    // 添加线段的两个端点
                    for (size_t i = 0; i < cell.m_coordinates.size(); ++i)
                    {
                        const auto& geo = cell.m_coordinates[i];

                        // 使用LLE2XYZ将经纬度转换为3D坐标
                        long double llx, lly, llz;
                        LLE2XYZ(geo.lon, geo.lat, 0.0, llx, lly, llz);

                        // 转换坐标系：MathDefine到OpenGL，并应用归一化
                        float x = static_cast<float>(llx) * scaleFactor * offsetRadius;
                        float y = static_cast<float>(llz) * scaleFactor * offsetRadius; // MathDefine的z对应OpenGL的y
                        float z = static_cast<float>(-lly) * scaleFactor * offsetRadius;
                        // MathDefine的y对应OpenGL的z，取反修复方向

                        m_overlayData.push_back(x);
                        m_overlayData.push_back(y);
                        m_overlayData.push_back(z);
                        m_overlayData.push_back(color.r);
                        m_overlayData.push_back(color.g);
                        m_overlayData.push_back(color.b);
                    }
                }
                else
                {
                    skippedCells++;
                }
            }
            else if (elementType == DGGSElementType::Cell)
            {
                // 处理面数据
                if (cell.m_coordinates.size() >= 3)
                {
                    processedCells++;

                    // 计算颜色 - 使用更强烈的对比度
                    glm::vec3 color(0.0f, 0.0f, 1.0f); // 默认蓝色

                    if (m_currentColorMap == ColorMapType::RGB && cell.values.size() >= 3)
                    {
                        // 多波段数据直接映射为RGB，增强亮度和对比度
                        color.r = static_cast<float>(std::min(255.0, std::max(0.0, cell.values[0])) / 255.0) * 1.5f;
                        color.g = static_cast<float>(std::min(255.0, std::max(0.0, cell.values[1])) / 255.0) * 1.5f;
                        color.b = static_cast<float>(std::min(255.0, std::max(0.0, cell.values[2])) / 255.0) * 1.5f;

                        // 确保颜色不超过1.0
                        color.r = std::min(1.0f, color.r);
                        color.g = std::min(1.0f, color.g);
                        color.b = std::min(1.0f, color.b);

                        // 添加对比度
                        float maxChannel = std::max(std::max(color.r, color.g), color.b);
                        if (maxChannel > 0.7f)
                        {
                            // 如果最大值超过0.7，提升所有通道值以增强亮度
                            color.r *= 1.2f;
                            color.g *= 1.2f;
                            color.b *= 1.2f;

                            // 再次确保颜色不超过1.0
                            color.r = std::min(1.0f, color.r);
                            color.g = std::min(1.0f, color.g);
                            color.b = std::min(1.0f, color.b);
                        }
                    }
                    else if (!cell.values.empty())
                    {
                        // 单波段数据使用色带
                        const float normalizedValue = static_cast<float>((cell.values[0] - minValue) / (maxValue -
                            minValue));
                        color = applyColorMap(normalizedValue, m_currentColorMap);

                        // 增强色带颜色的明度
                        color *= 1.3f;
                        color = glm::clamp(color, glm::vec3(0.0f), glm::vec3(1.0f));
                    }

                    // 通过三角形扇形方式添加面
                    for (size_t i = 1; i < cell.m_coordinates.size() - 1; ++i)
                    {
                        // 添加第一个顶点（中心点）
                        {
                            const auto& geo = cell.m_coordinates[0];

                            // 使用LLE2XYZ将经纬度转换为3D坐标
                            long double llx, lly, llz;
                            LLE2XYZ(geo.lon, geo.lat, 0.0, llx, lly, llz);

                            // 转换坐标系：MathDefine到OpenGL，并应用归一化
                            float x = static_cast<float>(llx) * scaleFactor * offsetRadius;
                            float y = static_cast<float>(llz) * scaleFactor * offsetRadius; // MathDefine的z对应OpenGL的y
                            float z = static_cast<float>(-lly) * scaleFactor * offsetRadius;
                            // MathDefine的y对应OpenGL的z，取反修复方向

                            // 轻微向外偏移，以确保可见性
                            glm::vec3 normal(x, y, z);
                            normal = glm::normalize(normal);

                            m_overlayData.push_back(x + normal.x * 0.0001f);
                            m_overlayData.push_back(y + normal.y * 0.0001f);
                            m_overlayData.push_back(z + normal.z * 0.0001f);
                            m_overlayData.push_back(color.r);
                            m_overlayData.push_back(color.g);
                            m_overlayData.push_back(color.b);
                        }

                        // 添加第二个顶点
                        {
                            const auto& geo = cell.m_coordinates[i];

                            // 使用LLE2XYZ将经纬度转换为3D坐标
                            long double llx, lly, llz;
                            LLE2XYZ(geo.lon, geo.lat, 0.0, llx, lly, llz);

                            // 转换坐标系：MathDefine到OpenGL，并应用归一化
                            float x = static_cast<float>(llx) * scaleFactor * offsetRadius;
                            float y = static_cast<float>(llz) * scaleFactor * offsetRadius; // MathDefine的z对应OpenGL的y
                            float z = static_cast<float>(-lly) * scaleFactor * offsetRadius;
                            // MathDefine的y对应OpenGL的z，取反修复方向

                            // 轻微向外偏移，以确保可见性
                            glm::vec3 normal(x, y, z);
                            normal = glm::normalize(normal);

                            m_overlayData.push_back(x + normal.x * 0.0001f);
                            m_overlayData.push_back(y + normal.y * 0.0001f);
                            m_overlayData.push_back(z + normal.z * 0.0001f);
                            m_overlayData.push_back(color.r);
                            m_overlayData.push_back(color.g);
                            m_overlayData.push_back(color.b);
                        }

                        // 添加第三个顶点
                        {
                            const auto& geo = cell.m_coordinates[i + 1];

                            // 使用LLE2XYZ将经纬度转换为3D坐标
                            long double llx, lly, llz;
                            LLE2XYZ(geo.lon, geo.lat, 0.0, llx, lly, llz);

                            // 转换坐标系：MathDefine到OpenGL，并应用归一化
                            float x = static_cast<float>(llx) * scaleFactor * offsetRadius;
                            float y = static_cast<float>(llz) * scaleFactor * offsetRadius; // MathDefine的z对应OpenGL的y
                            float z = static_cast<float>(-lly) * scaleFactor * offsetRadius;
                            // MathDefine的y对应OpenGL的z，取反修复方向

                            // 轻微向外偏移，以确保可见性
                            glm::vec3 normal(x, y, z);
                            normal = glm::normalize(normal);

                            m_overlayData.push_back(x + normal.x * 0.0001f);
                            m_overlayData.push_back(y + normal.y * 0.0001f);
                            m_overlayData.push_back(z + normal.z * 0.0001f);
                            m_overlayData.push_back(color.r);
                            m_overlayData.push_back(color.g);
                            m_overlayData.push_back(color.b);
                        }
                    }
                }
                else
                {
                    skippedCells++;
                }
            }
        }

        // 更新VBO
        if (!m_overlayData.empty())
        {
            // 删除旧的VBO如果存在
            if (m_overlayVBO != 0)
            {
                glDeleteBuffers(1, &m_overlayVBO);
                m_overlayVBO = 0;
            }

            // 创建新的VBO
            glGenBuffers(1, &m_overlayVBO);
            std::cout << "创建新的VBO，ID: " << m_overlayVBO << std::endl;

            // 绑定并上传数据
            glBindBuffer(GL_ARRAY_BUFFER, m_overlayVBO);

            glBufferData(GL_ARRAY_BUFFER, m_overlayData.size() * sizeof(float), m_overlayData.data(), GL_STATIC_DRAW);

            glBindBuffer(GL_ARRAY_BUFFER, 0);

            // 设置标志
            m_hasOverlayData = true;

            std::cout << "覆盖数据上传至GPU成功，大小: " << (m_overlayData.size() * sizeof(float)) << " 字节" << std::endl;
        }
        else
        {
            m_hasOverlayData = false;
            std::cout << "未生成覆盖数据" << std::endl;
        }
    }

    GeoCoordinate Earth::handleMouseClick(int x, int y)
    {
        // 将屏幕坐标转换为经纬度
        m_selectedCoordinate = screenToGeo(x, y);

        // 如果成功获取经纬度，显示标识
        if (m_selectedCoordinate.isValid)
        {
            m_showCoordinateLabel = true;
        }
        else
        {
            m_showCoordinateLabel = false;
            std::cout << "无法确定点击位置的经纬度" << std::endl;
        }

        return m_selectedCoordinate;
    }

    GeoCoordinate Earth::screenToGeo(int x, int y)
    {
        // 将屏幕坐标转换为归一化设备坐标 (NDC)
        float ndcX = (2.0f * x) / m_windowWidth - 1.0f;
        float ndcY = 1.0f - (2.0f * y) / m_windowHeight; // Y轴需要反转

        // 创建裁剪空间坐标
        glm::vec4 clipCoords(ndcX, ndcY, -1.0f, 1.0f);

        // 从裁剪空间转换到视图空间
        glm::mat4 invProjection = glm::inverse(m_projectionMatrix);
        glm::vec4 eyeCoords = invProjection * clipCoords;
        eyeCoords = glm::vec4(eyeCoords.x, eyeCoords.y, -1.0f, 0.0f);

        // 从视图空间转换到世界空间
        glm::mat4 invView = glm::inverse(m_viewMatrix);
        glm::vec4 rayWorld = invView * eyeCoords;
        glm::vec3 rayDirection = glm::normalize(glm::vec3(rayWorld));

        // 相机位置
        glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, m_zoom);

        float a = glm::dot(rayDirection, rayDirection);
        float b = 2.0f * glm::dot(rayDirection, cameraPos);
        float c = glm::dot(cameraPos, cameraPos) - 1.0f; // 球体半径为1

        float discriminant = b * b - 4 * a * c;

        GeoCoordinate result = {0.0, 0.0, false};

        if (discriminant >= 0)
        {
            // 射线与球体相交
            float t = (-b - sqrt(discriminant)) / (2.0f * a);

            if (t > 0)
            {
                // 计算交点
                glm::vec3 intersectionPoint = cameraPos + t * rayDirection;

                // 调整模型旋转
                glm::mat4 invModel = glm::inverse(m_modelMatrix);
                glm::vec4 rotatedPoint = invModel * glm::vec4(intersectionPoint, 1.0f);
                intersectionPoint = glm::vec3(rotatedPoint);

                // 转换为单位球面上的点
                intersectionPoint = glm::normalize(intersectionPoint);

                // 使用MathDefine.hpp中的XYZ2LLE函数计算经纬度
                double lon, lat, elev;

                double x = intersectionPoint.x;
                double y = -intersectionPoint.z; // 注意：这里取反，修复经度方向问题
                double z = intersectionPoint.y; // OpenGL的y对应球面坐标系的z

                // 调用MathDefine中的函数
                XYZ2LLE(x, y, z, lon, lat, elev);

                result.lat = lat;
                result.lon = lon;
                result.isValid = true;
            }
        }

        return result;
    }

    void Earth::renderCoordinateLabel()
    {
        if (!m_selectedCoordinate.isValid) return;

        // 使用MathDefine.hpp中的LLE2XYZ函数将经纬度转换为3D空间中的点
        double lon = m_selectedCoordinate.lon;
        double lat = m_selectedCoordinate.lat;
        double elev = 0.0; // 表面上，无高程

        long double x, y, z;
        // 调用LLE2XYZ，注意坐标系转换
        LLE2XYZ(lon, lat, elev, x, y, z);

        // 计算缩放因子
        float scaleFactor = 1.0f / static_cast<float>(earthRadius);

        // 将坐标从MathDefine的系统转换到OpenGL系统
        // MathDefine: x指向经度0，z指向北极
        // OpenGL: x同样指向经度0，但y指向上(北极)
        // 注意：为了保持与screenToGeo方法中的坐标转换一致，这里y坐标取反
        float openglX = static_cast<float>(x) * scaleFactor * 1.02f; // 稍微扩大半径
        float openglY = static_cast<float>(z) * scaleFactor * 1.02f; // MathDefine的z对应OpenGL的y
        float openglZ = static_cast<float>(-y) * scaleFactor * 1.02f; // MathDefine的y对应OpenGL的z，取反修复方向

        // 标记点
        glUseProgram(m_overlayShaderProgram);

        // 设置矩阵
        GLint modelLoc = glGetUniformLocation(m_overlayShaderProgram, "model");
        GLint viewLoc = glGetUniformLocation(m_overlayShaderProgram, "view");
        GLint projectionLoc = glGetUniformLocation(m_overlayShaderProgram, "projection");
        GLint geometryTypeLoc = glGetUniformLocation(m_overlayShaderProgram, "geometryType");

        glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(m_modelMatrix));
        glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(m_viewMatrix));
        glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(m_projectionMatrix));
        glUniform1i(geometryTypeLoc, 0); // 点类型

        // 创建一个标记点
        float markerPoint[] = {
            openglX, openglY, openglZ, // 位置
            1.0f, 1.0f, 0.0f // 黄色
        };

        // 绘制标记点
        GLuint tempVBO, tempVAO;
        glGenBuffers(1, &tempVBO);
        glGenVertexArrays(1, &tempVAO);

        glBindVertexArray(tempVAO);
        glBindBuffer(GL_ARRAY_BUFFER, tempVBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(markerPoint), markerPoint, GL_STATIC_DRAW);

        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), static_cast<void*>(nullptr));
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), reinterpret_cast<void*>(3 * sizeof(float)));

        glPointSize(10.0f);
        glDrawArrays(GL_POINTS, 0, 1);

        // 清理
        glBindVertexArray(0);
        glDeleteBuffers(1, &tempVBO);
        glDeleteVertexArrays(1, &tempVAO);
        glUseProgram(0);
    }

    void Earth::renderHelpText()
    {
        // 如果没有预渲染的帮助面板纹理或者需要更新
        if (m_helpPanelTexture == 0 || m_helpPanelNeedsUpdate)
        {
            // 尝试创建或更新帮助面板纹理
            if (!createHelpPanelTexture())
            {
                std::cerr << "无法创建帮助面板纹理，跳过渲染" << std::endl;
                return;
            }
        }
        
        // 保存当前OpenGL状态
        GLboolean depthTestEnabled;
        glGetBooleanv(GL_DEPTH_TEST, &depthTestEnabled);
        
        // 禁用深度测试，确保文本始终显示在最前面
        glDisable(GL_DEPTH_TEST);
        
        // 启用混合
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        
        // 设置正交投影矩阵
        glm::mat4 orthoProjection = glm::ortho(
            0.0f, static_cast<float>(m_windowWidth),
            0.0f, static_cast<float>(m_windowHeight)
        );
        
        // 创建简单的着色器程序用于渲染帮助面板
        static GLuint panelShaderProgram = 0;
        
        if (panelShaderProgram == 0)
        {
            // 顶点着色器源代码
            const char* HelpVertexShaderSource = R"(
                #version 330 core
                layout (location = 0) in vec2 aPos;
                layout (location = 1) in vec2 aTexCoord;
                
                out vec2 TexCoord;
                
                uniform mat4 projection;
                uniform mat4 model;
                
                void main()
                {
                    gl_Position = projection * model * vec4(aPos, 0.0, 1.0);
                    TexCoord = aTexCoord;
                }
            )";
            
            // 片段着色器源代码
            const char* HelpFragmentShaderSource = R"(
                #version 330 core
                in vec2 TexCoord;
                
                out vec4 FragColor;
                
                uniform sampler2D panelTexture;
                
                void main()
                {
                    FragColor = texture(panelTexture, TexCoord);
                }
            )";
            
            // 创建和编译着色器
            GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
            glShaderSource(vertexShader, 1, &HelpVertexShaderSource, nullptr);
            glCompileShader(vertexShader);
            
            GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
            glShaderSource(fragmentShader, 1, &HelpFragmentShaderSource, nullptr);
            glCompileShader(fragmentShader);
            
            // 创建程序并链接着色器
            panelShaderProgram = glCreateProgram();
            glAttachShader(panelShaderProgram, vertexShader);
            glAttachShader(panelShaderProgram, fragmentShader);
            glLinkProgram(panelShaderProgram);
            
            // 清理
            glDeleteShader(vertexShader);
            glDeleteShader(fragmentShader);
            
            // 检查链接错误
            GLint success;
            glGetProgramiv(panelShaderProgram, GL_LINK_STATUS, &success);
            if (!success)
            {
                char infoLog[512];
                glGetProgramInfoLog(panelShaderProgram, 512, nullptr, infoLog);
                std::cerr << "面板着色器程序链接失败: " << infoLog << std::endl;
                return;
            }
        }
        
        // 使用着色器程序
        glUseProgram(panelShaderProgram);
        
        // 绑定VAO和纹理
        glBindVertexArray(m_panelVAO);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, m_helpPanelTexture);
        
        // 设置采样器
        GLint textureLoc = glGetUniformLocation(panelShaderProgram, "panelTexture");
        glUniform1i(textureLoc, 0);
        
        // 设置投影矩阵
        GLint projLoc = glGetUniformLocation(panelShaderProgram, "projection");
        glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(orthoProjection));
        
        // 设置模型矩阵（位置和大小）
        float panelX = 10.0f;
        float panelY = m_windowHeight - 350.0f; // 向上调整面板位置，留出更多空间
        float panelWidth = 440.0f; // 增加面板宽度，与createHelpPanelTexture()一致
        float panelHeight = 340.0f; // 保持面板高度，与创建表面保持一致
        
        glm::mat4 modelMatrix = glm::mat4(1.0f);
        modelMatrix = glm::translate(modelMatrix, glm::vec3(panelX, panelY, 0.0f));
        modelMatrix = glm::scale(modelMatrix, glm::vec3(panelWidth, panelHeight, 1.0f));
        
        GLint modelLoc = glGetUniformLocation(panelShaderProgram, "model");
        glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(modelMatrix));
        
        // 绘制面板
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
        
        // 检查OpenGL错误
        GLenum error = glGetError();
        if (error != GL_NO_ERROR)
        {
            std::cerr << "OpenGL错误(帮助面板绘制): " << error << std::endl;
        }
        
        // 恢复OpenGL状态
        if (depthTestEnabled)
        {
            glEnable(GL_DEPTH_TEST);
        }
        glDisable(GL_BLEND);
        glBindVertexArray(0);
        glBindTexture(GL_TEXTURE_2D, 0);
        glUseProgram(0);
    }

    void Earth::adjustOverlayAlpha(float delta)
    {
        // 调整透明度值，确保在[0.1, 1.0]范围内
        m_overlayAlpha += delta;
        if (m_overlayAlpha > 1.0f)
        {
            m_overlayAlpha = 1.0f;
        }
        else if (m_overlayAlpha < 0.1f)
        {
            m_overlayAlpha = 0.1f;
        }

        std::cout << "覆盖数据透明度: " << m_overlayAlpha << std::endl;
    }

    bool Earth::initTTF()
    {
        // 初始化SDL_ttf
        if (TTF_Init() == -1)
        {
            std::cerr << "SDL_ttf初始化失败: " << TTF_GetError() << std::endl;
            return false;
        }
        
        // 加载字体，尝试不同的路径
        const char* fontPaths[] = {
            "C:/Windows/Fonts/simsun.ttc",    // 宋体
            "C:/Windows/Fonts/msyh.ttc",      // 微软雅黑
            "C:/Windows/Fonts/simhei.ttf",    // 黑体
            "C:/Windows/Fonts/Arial.ttf",     // Arial (备选拉丁字体)
            "fonts/simsun.ttc",               // 相对路径尝试
            "fonts/msyh.ttc"                  // 相对路径尝试
        };
        
        // 尝试加载字体，调整为更大的字体大小以确保清晰
        for (const char* fontPath : fontPaths)
        {
            // 适当降低字体大小 - 24像素点，兼顾清晰度和布局
            m_font = TTF_OpenFont(fontPath, 24);
            if (m_font != nullptr)
            {
                std::cout << "成功加载字体: " << fontPath << " (大小: 24)" << std::endl;
                // 设置字体样式为正常，避免加粗导致的渲染问题
                TTF_SetFontStyle(m_font, TTF_STYLE_NORMAL);
                
                // 设置字体微调提示以获得最佳清晰度
                TTF_SetFontHinting(m_font, TTF_HINTING_LIGHT);
                
                // 创建初始帮助面板纹理
                createHelpPanelTexture();
                
                return true;
            }
        }
        
        // 如果加载失败，尝试更小的字体大小
        if (m_font == nullptr)
        {
            for (const char* fontPath : fontPaths)
            {
                m_font = TTF_OpenFont(fontPath, 20);
                if (m_font != nullptr)
                {
                    std::cout << "成功加载字体: " << fontPath << " (大小: 20)" << std::endl;
                    TTF_SetFontStyle(m_font, TTF_STYLE_NORMAL);
                    TTF_SetFontHinting(m_font, TTF_HINTING_LIGHT);
                    
                    // 创建初始帮助面板纹理
                    createHelpPanelTexture();
                    
                    return true;
                }
            }
        }
        
        // 如果所有字体都加载失败
        if (m_font == nullptr)
        {
            std::cerr << "无法加载任何字体: " << TTF_GetError() << std::endl;
            return false;
        }
        
        return false;
    }
    
    bool Earth::createHelpPanelTexture()
    {
        if (m_font == nullptr)
        {
            std::cerr << "未加载字体，无法创建帮助面板纹理" << std::endl;
            return false;
        }
        
        // 创建一个临时表面来渲染所有内容
        int panelWidth = 440; // 增加面板宽度从420px到440px
        int panelHeight = 400; // 保持面板高度，确保底部内容完全显示
        
        // 创建表面，使用32位RGBA格式
        SDL_Surface* panelSurface = SDL_CreateRGBSurface(
            0, panelWidth, panelHeight, 32,
            0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000
        );
        
        if (!panelSurface)
        {
            std::cerr << "无法创建面板表面: " << SDL_GetError() << std::endl;
            return false;
        }
        
        // 填充背景为深蓝色半透明背景，与新截图颜色匹配
        SDL_FillRect(panelSurface, nullptr, SDL_MapRGBA(panelSurface->format, 20, 15, 80, 230));
        
        // 定义文本颜色 - 调整颜色使其更适合深蓝色背景
        SDL_Color white = {255, 255, 255, 255};
        SDL_Color cyan = {0, 255, 255, 255};       // 使用青色替代黄色作为标题
        SDL_Color lightGreen = {180, 255, 180, 255};
        
        // 保存当前字体大小以便后续恢复
        int originalFontSize = TTF_FontHeight(m_font);
        TTF_Font* titleFont = TTF_OpenFont(TTF_FontFaceFamilyName(m_font), 28); // 为标题创建更大的字体
        
        // 绘制标题
        SDL_Surface* titleSurface = nullptr;
        if (titleFont) {
            titleSurface = TTF_RenderUTF8_Blended(titleFont, "快捷键帮助", cyan);
            TTF_CloseFont(titleFont);
        } else {
            // 如果无法创建更大字体，则使用当前字体
            titleSurface = TTF_RenderUTF8_Blended(m_font, "快捷键帮助", cyan);
        }
        
        if (titleSurface)
        {
            SDL_Rect titleRect = {20, 15, titleSurface->w, titleSurface->h};
            SDL_BlitSurface(titleSurface, nullptr, panelSurface, &titleRect);
            SDL_FreeSurface(titleSurface);
        }
        
        // 绘制分隔线
        SDL_Rect lineRect = {20, 55, 400, 2}; // 增加分隔线长度，与增加的面板宽度匹配
        SDL_FillRect(panelSurface, &lineRect, SDL_MapRGBA(panelSurface->format, 255, 255, 255, 255));
        
        // 设置帮助文本的起始位置和行间距
        int startY = 70;
        int lineHeight = 30; // 保持之前调整的行高
        int column2X = 210;  // 增加列间距，给快捷键提供更多空间
        
        // 帮助文本的键和描述
        struct HelpItem {
            const char* key;
            const char* description;
        };
        
        // 定义帮助项
        HelpItem helpItems[] = {
            {"TAB:", "显示/隐藏此帮助"},
            {"1-7:", "切换色带类型"},
            {"G:", "显示/隐藏经纬网"},
            {"L:", "显示/隐藏经纬度标注"},
            {"O:", "打开单个文件"},
            {"Shift+O:", "打开多个文件"},
            {"鼠标:", "点击获取坐标/拖拽旋转"},
            {"上/下键:", "调整数据透明度"},
            {"R:", "重置视图"},
            {"F:", "全屏切换"},
            {"鼠标滚轮:", "缩放"}
        };
        
        // 绘制帮助项
        for (int i = 0; i < 11; i++)
        {
            int y = startY + i * lineHeight;
            
            // 绘制键
            SDL_Surface* keySurface = TTF_RenderUTF8_Blended(m_font, helpItems[i].key, white);
            if (keySurface)
            {
                SDL_Rect keyRect = {20, y, keySurface->w, keySurface->h};
                SDL_BlitSurface(keySurface, nullptr, panelSurface, &keyRect);
                SDL_FreeSurface(keySurface);
            }
            
            // 绘制描述
            SDL_Surface* descSurface = TTF_RenderUTF8_Blended(m_font, helpItems[i].description, lightGreen);
            if (descSurface)
            {
                SDL_Rect descRect = {column2X, y, descSurface->w, descSurface->h};
                SDL_BlitSurface(descSurface, nullptr, panelSurface, &descRect);
                SDL_FreeSurface(descSurface);
            }
        }
        
        // 如果已经有一个纹理，先删除它
        if (m_helpPanelTexture != 0)
        {
            glDeleteTextures(1, &m_helpPanelTexture);
        }
        
        // 创建OpenGL纹理
        glGenTextures(1, &m_helpPanelTexture);
        glBindTexture(GL_TEXTURE_2D, m_helpPanelTexture);
        
        // 设置纹理参数
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        
        // 上传纹理数据
        glTexImage2D(
            GL_TEXTURE_2D,
            0,
            GL_RGBA,
            panelSurface->w,
            panelSurface->h,
            0,
            GL_RGBA,
            GL_UNSIGNED_BYTE,
            panelSurface->pixels
        );
        
        // 检查是否有错误
        GLenum error = glGetError();
        if (error != GL_NO_ERROR)
        {
            std::cerr << "创建帮助面板纹理时发生OpenGL错误: " << error << std::endl;
        }
        
        // 释放表面
        SDL_FreeSurface(panelSurface);
        
        // 标记帮助面板不需要更新
        m_helpPanelNeedsUpdate = false;
        
        return true;
    }

    void Earth::createGrid()
    {
        // 使用当前缩放级别创建自适应密度的经纬网
        float longitudeStep = getLongitudeStep(m_zoom);
        float latitudeStep = getLatitudeStep(m_zoom);
        
        createAdaptiveGrid(m_zoom);
        
        // 创建经纬网标注
        renderGridLabels(longitudeStep, latitudeStep);
        
        // 更新最后一次创建经纬网时的缩放级别
        m_lastGridZoom = m_zoom;
    }
    
    bool Earth::needGridUpdate() const
    {
        // 如果缩放变化超过阈值，则需要更新经纬网
        return std::abs(m_zoom - m_lastGridZoom) > m_gridZoomThreshold;
    }
    
    float Earth::getLongitudeStep(float zoomLevel) const
    {
        // 反转逻辑：缩放值越小，间隔越小（网格越密集）
        // 缩放值越大，间隔越大（网格越稀疏）
        if (zoomLevel <= 1.0f)
        {
            return 2.0f; // 最远时，每2度一条经线（最密集）
        }
        else if (zoomLevel <= 1.5f)
        {
            return 5.0f; // 较远时，每5度一条经线
        }
        else if (zoomLevel <= 2.0f)
        {
            return 10.0f; // 中等距离时，每10度一条经线
        }
        else if (zoomLevel <= 2.5f)
        {
            return 15.0f; // 较近时，每15度一条经线
        }
        else
        {
            return 30.0f; // 最近时，每30度一条经线（最稀疏）
        }
    }
    
    float Earth::getLatitudeStep(float zoomLevel) const
    {
        // 使用与经度相同的间隔策略
        return getLongitudeStep(zoomLevel);
    }
    
    void Earth::createAdaptiveGrid(float zoomLevel)
    {
        // 清空现有网格数据
        m_gridData.clear();
        
        // 计算地球的缩放因子，确保与地球模型使用相同的缩放
        float scaleFactor = 1.0f / static_cast<float>(earthRadius);
        
        // 定义经纬网的半径，稍微大于地球模型
        float gridRadius = 1.002f; // 微小偏移，确保网格在地球表面上方
        
        // 根据缩放级别获取经纬线的间隔
        const float longitudeStep = getLongitudeStep(zoomLevel);
        const float latitudeStep = getLatitudeStep(zoomLevel);
        
        // 经线 - 从-180度到180度
        for (float lon = -180.0f; lon <= 180.0f; lon += longitudeStep)
        {
            // 跳过-180和180的重复线
            if (std::abs(lon) == 180.0f && lon > -180.0f) continue;
            
            // 沿着纬度从南极到北极绘制一条经线
            for (float lat = -90.0f; lat <= 90.0f; lat += 1.0f)
            {
                // 使用LLE2XYZ函数将经纬度坐标转换为3D坐标
                long double x, y, z;
                LLE2XYZ(lon, lat, 0.0, x, y, z);
                
                // 应用缩放和偏移
                x *= scaleFactor * gridRadius;
                y *= scaleFactor * gridRadius;
                z *= scaleFactor * gridRadius;
                
                // 转换坐标系：MathDefine到OpenGL
                float openglX = static_cast<float>(x);
                float openglY = static_cast<float>(z); // MathDefine的z对应OpenGL的y
                float openglZ = static_cast<float>(-y); // MathDefine的y对应OpenGL的z，取反修复方向
                
                // 定义经线颜色为浅蓝色
                float r = 0.5f; // 浅蓝色
                float g = 0.7f;
                float b = 1.0f;
                
                // 添加顶点和颜色数据
                m_gridData.push_back(openglX);
                m_gridData.push_back(openglY);
                m_gridData.push_back(openglZ);
                m_gridData.push_back(r);
                m_gridData.push_back(g);
                m_gridData.push_back(b);
            }
        }
        
        // 纬线 - 从-90度到90度（不包括南北极点）
        for (float lat = -90.0f + latitudeStep; lat < 90.0f; lat += latitudeStep)
        {
            // 沿着经度从-180度到180度绘制一条纬线
            for (float lon = -180.0f; lon <= 180.0f; lon += 1.0f)
            {
                // 使用LLE2XYZ函数将经纬度坐标转换为3D坐标
                long double x, y, z;
                LLE2XYZ(lon, lat, 0.0, x, y, z);
                
                // 应用缩放和偏移
                x *= scaleFactor * gridRadius;
                y *= scaleFactor * gridRadius;
                z *= scaleFactor * gridRadius;
                
                // 转换坐标系：MathDefine到OpenGL
                float openglX = static_cast<float>(x);
                float openglY = static_cast<float>(z); // MathDefine的z对应OpenGL的y
                float openglZ = static_cast<float>(-y); // MathDefine的y对应OpenGL的z，取反修复方向
                
                // 定义纬线颜色为淡黄色
                float r = 1.0f; // 淡黄色
                float g = 0.9f;
                float b = 0.5f;
                
                // 添加顶点和颜色数据
                m_gridData.push_back(openglX);
                m_gridData.push_back(openglY);
                m_gridData.push_back(openglZ);
                m_gridData.push_back(r);
                m_gridData.push_back(g);
                m_gridData.push_back(b);
            }
        }
        
        // 赤道使用不同颜色（红色）
        float lat = 0.0f;
        for (float lon = -180.0f; lon <= 180.0f; lon += 1.0f)
        {
            // 使用LLE2XYZ函数将经纬度坐标转换为3D坐标
            long double x, y, z;
            LLE2XYZ(lon, lat, 0.0, x, y, z);
            
            // 应用缩放和偏移
            x *= scaleFactor * gridRadius;
            y *= scaleFactor * gridRadius;
            z *= scaleFactor * gridRadius;
            
            // 转换坐标系：MathDefine到OpenGL
            float openglX = static_cast<float>(x);
            float openglY = static_cast<float>(z); // MathDefine的z对应OpenGL的y
            float openglZ = static_cast<float>(-y); // MathDefine的y对应OpenGL的z，取反修复方向
            
            // 赤道使用红色
            float r = 1.0f; // 红色
            float g = 0.2f;
            float b = 0.2f;
            
            // 添加顶点和颜色数据
            m_gridData.push_back(openglX);
            m_gridData.push_back(openglY);
            m_gridData.push_back(openglZ);
            m_gridData.push_back(r);
            m_gridData.push_back(g);
            m_gridData.push_back(b);
        }
        
        // 本初子午线使用不同颜色（绿色）
        float lon = 0.0f;
        for (float lat = -90.0f; lat <= 90.0f; lat += 1.0f)
        {
            // 使用LLE2XYZ函数将经纬度坐标转换为3D坐标
            long double x, y, z;
            LLE2XYZ(lon, lat, 0.0, x, y, z);
            
            // 应用缩放和偏移
            x *= scaleFactor * gridRadius;
            y *= scaleFactor * gridRadius;
            z *= scaleFactor * gridRadius;
            
            // 转换坐标系：MathDefine到OpenGL
            float openglX = static_cast<float>(x);
            float openglY = static_cast<float>(z); // MathDefine的z对应OpenGL的y
            float openglZ = static_cast<float>(-y); // MathDefine的y对应OpenGL的z，取反修复方向
            
            // 本初子午线使用绿色
            float r = 0.2f; // 绿色
            float g = 1.0f;
            float b = 0.2f;
            
            // 添加顶点和颜色数据
            m_gridData.push_back(openglX);
            m_gridData.push_back(openglY);
            m_gridData.push_back(openglZ);
            m_gridData.push_back(r);
            m_gridData.push_back(g);
            m_gridData.push_back(b);
        }
        
        // 创建或更新OpenGL缓冲对象
        if (m_gridVAO == 0)
        {
            glGenVertexArrays(1, &m_gridVAO);
        }
        
        if (m_gridVBO == 0)
        {
            glGenBuffers(1, &m_gridVBO);
        }
        
        // 绑定VAO和VBO
        glBindVertexArray(m_gridVAO);
        glBindBuffer(GL_ARRAY_BUFFER, m_gridVBO);
        
        // 上传数据到GPU
        glBufferData(GL_ARRAY_BUFFER, m_gridData.size() * sizeof(float), m_gridData.data(), GL_STATIC_DRAW);
        
        // 设置顶点属性指针
        // 位置属性
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(0);
        
        // 颜色属性
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
        glEnableVertexAttribArray(1);
        
        // 解绑
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(0);
    }

    void Earth::renderGrid()
    {
        if (m_gridVAO == 0 || m_gridData.empty())
        {
            return;
        }
        
        // 保存当前OpenGL状态
        GLboolean depthMaskEnabled;
        glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMaskEnabled);
        
        // 启用混合
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        
        // 设置深度测试
        glDepthMask(GL_FALSE); // 禁用深度写入，确保网格始终显示
        
        // 使用覆盖数据着色器（与overlay使用相同的着色器程序）
        glUseProgram(m_overlayShaderProgram);
        
        // 设置矩阵
        GLint modelLoc = glGetUniformLocation(m_overlayShaderProgram, "model");
        GLint viewLoc = glGetUniformLocation(m_overlayShaderProgram, "view");
        GLint projectionLoc = glGetUniformLocation(m_overlayShaderProgram, "projection");
        
        glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(m_modelMatrix));
        glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(m_viewMatrix));
        glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(m_projectionMatrix));
        
        // 设置几何类型为线
        GLint geometryTypeLoc = glGetUniformLocation(m_overlayShaderProgram, "geometryType");
        glUniform1i(geometryTypeLoc, 1); // 1代表线
        
        // 设置透明度（经纬网使用固定透明度0.6）
        GLint alphaLoc = glGetUniformLocation(m_overlayShaderProgram, "overlayAlpha");
        glUniform1f(alphaLoc, 0.6f);
        
        // 绑定VAO
        glBindVertexArray(m_gridVAO);
        
        // 设置线宽
        glLineWidth(1.0f);
        
        // 绘制经纬线
        glDrawArrays(GL_LINE_STRIP, 0, m_gridData.size() / 6);
        
        // 恢复OpenGL状态
        glDepthMask(depthMaskEnabled);
        glDisable(GL_BLEND);
        glBindVertexArray(0);
        glUseProgram(0);
    }

    void Earth::renderGridLabels(float longitudeStep, float latitudeStep)
    {
        // 清空现有网格标注数据
        m_gridLabels.clear();

        // 计算经纬网标注的间隔
        float longitudeInterval = longitudeStep; // 使用与网格相同的间隔
        float latitudeInterval = latitudeStep; // 使用与网格相同的间隔

        // 计算地球的缩放因子
        float scaleFactor = 1.0f / static_cast<float>(earthRadius);
        
        // 定义标注位置的半径，稍微大于经纬网的半径
        float labelRadius = 1.003f; // 确保标注在网格之上

        // 经度标注（在赤道上标注）
        for (float lon = -180.0f; lon <= 180.0f; lon += longitudeInterval)
        {
            // 跳过-180和180的重复标注
            if (std::abs(lon) == 180.0f && lon > -180.0f) continue;
            
            // 标注放在赤道上
            float lat = 0.0f;
            
            // 使用LLE2XYZ函数将经纬度坐标转换为3D坐标
            long double x, y, z;
            LLE2XYZ(lon, lat, 0.0, x, y, z);
            
            // 应用缩放和偏移
            x *= scaleFactor * labelRadius;
            y *= scaleFactor * labelRadius;
            z *= scaleFactor * labelRadius;
            
            // 转换坐标系：MathDefine到OpenGL
            float openglX = static_cast<float>(x);
            float openglY = static_cast<float>(z); // MathDefine的z对应OpenGL的y
            float openglZ = static_cast<float>(-y); // MathDefine的y对应OpenGL的z，取反修复方向
            
            // 创建标注文本
            std::string text;
            if (lon == 0.0f)
            {
                text = "0"; // 本初子午线特殊标注，简化为数字
            }
            else
            {
                // 格式化经度文本，使用ASCII字符
                std::ostringstream oss;
                oss << std::abs(lon) << (lon < 0 ? "W" : "E");
                text = oss.str();
            }
            
            // 添加到标注集合
            m_gridLabels.push_back({openglX, openglY, openglZ, text, true});
        }
        
        // 纬度标注（在本初子午线上标注）
        for (float lat = -90.0f + latitudeInterval; lat < 90.0f; lat += latitudeInterval)
        {
            // 标注放在本初子午线上
            float lon = 0.0f;
            
            // 使用LLE2XYZ函数将经纬度坐标转换为3D坐标
            long double x, y, z;
            LLE2XYZ(lon, lat, 0.0, x, y, z);
            
            // 应用缩放和偏移
            x *= scaleFactor * labelRadius;
            y *= scaleFactor * labelRadius;
            z *= scaleFactor * labelRadius;
            
            // 转换坐标系：MathDefine到OpenGL
            float openglX = static_cast<float>(x);
            float openglY = static_cast<float>(z); // MathDefine的z对应OpenGL的y
            float openglZ = static_cast<float>(-y); // MathDefine的y对应OpenGL的z，取反修复方向
            
            // 创建标注文本
            std::string text;
            if (lat == 0.0f)
            {
                text = "EQ"; // 赤道特殊标注，使用简短英文缩写
            }
            else
            {
                // 格式化纬度文本，使用ASCII字符
                std::ostringstream oss;
                oss << std::abs(lat) << (lat < 0 ? "S" : "N");
                text = oss.str();
            }
            
            // 添加到标注集合
            m_gridLabels.push_back({openglX, openglY, openglZ, text, false});
        }

        if (m_font == nullptr)
        {
            std::cerr << "未加载字体，无法渲染经纬网标注" << std::endl;
            return;
        }

        // 创建纹理图集 - 预先渲染所有标签
        if (m_labelTextureAtlas != 0)
        {
            glDeleteTextures(1, &m_labelTextureAtlas);
            m_labelTextureAtlas = 0;
        }
        
        // 为每个标签创建临时表面
        std::vector<SDL_Surface*> labelSurfaces;
        std::vector<glm::vec2> textureDimensions;
        
        // 计算需要的总纹理大小
        int totalWidth = 0;
        int maxHeight = 0;
        
        for (const auto& label : m_gridLabels)
        {
            // 设置颜色：经度标注为蓝色，纬度标注为橙色
            SDL_Color textColor = label.isLongitude
                ? SDL_Color{100, 150, 255, 255} // 蓝色
                : SDL_Color{255, 150, 50, 255}; // 橙色
            
            // 尝试使用Text而不是UTF8
            SDL_Surface* textSurface = TTF_RenderText_Blended(m_font, label.text.c_str(), textColor);
            if (textSurface)
            {
                labelSurfaces.push_back(textSurface);
                textureDimensions.push_back(glm::vec2(textSurface->w, textSurface->h));
                totalWidth += textSurface->w + 2; // 添加边距
                maxHeight = std::max(maxHeight, textSurface->h);
            }
            else
            {
                std::cerr << "无法渲染文本: " << label.text << ", 错误: " << TTF_GetError() << std::endl;
                labelSurfaces.push_back(nullptr);
                textureDimensions.push_back(glm::vec2(0, 0));
            }
        }
        
        // 确保宽度为2的幂
        int atlasWidth = 512; // 预设一个合理的大小
        while (atlasWidth < totalWidth) atlasWidth *= 2;
        int atlasHeight = maxHeight + 4; // 添加一些边距
        
        // 创建纹理图集表面
        SDL_Surface* atlasSurface = SDL_CreateRGBSurface(
            0, atlasWidth, atlasHeight, 32,
            0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000
        );
        
        if (!atlasSurface)
        {
            std::cerr << "无法创建标签纹理图集表面: " << SDL_GetError() << std::endl;
            // 清理表面
            for (SDL_Surface* surface : labelSurfaces)
            {
                if (surface) SDL_FreeSurface(surface);
            }
            return;
        }
        
        // 清除图集表面为透明
        SDL_FillRect(atlasSurface, nullptr, SDL_MapRGBA(atlasSurface->format, 0, 0, 0, 0));
        
        // 将每个标签复制到图集表面
        int currentX = 0;
        std::vector<glm::vec4> textureCoords; // x, y, width, height in atlas
        
        for (size_t i = 0; i < labelSurfaces.size(); ++i)
        {
            SDL_Surface* surface = labelSurfaces[i];
            if (surface)
            {
                SDL_Rect destRect = {currentX, 2, surface->w, surface->h};
                SDL_BlitSurface(surface, nullptr, atlasSurface, &destRect);
                
                // 保存纹理坐标（标准化）
                float x1 = static_cast<float>(currentX) / atlasWidth;
                float y1 = 2.0f / atlasHeight;
                float x2 = static_cast<float>(currentX + surface->w) / atlasWidth;
                float y2 = static_cast<float>(2 + surface->h) / atlasHeight;
                
                textureCoords.push_back(glm::vec4(x1, y1, x2, y2));
                
                currentX += surface->w + 2; // 添加边距
                SDL_FreeSurface(surface);
            }
            else
            {
                textureCoords.push_back(glm::vec4(0, 0, 0, 0));
            }
        }
        
        // 创建OpenGL纹理图集
        glGenTextures(1, &m_labelTextureAtlas);
        glBindTexture(GL_TEXTURE_2D, m_labelTextureAtlas);
        
        // 设置纹理参数
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        
        // 确定格式
        GLenum format = (atlasSurface->format->BytesPerPixel == 4)
            ? ((atlasSurface->format->Rmask == 0x000000ff) ? GL_RGBA : GL_BGRA)
            : ((atlasSurface->format->Rmask == 0x000000ff) ? GL_RGB : GL_BGR);
        
        // 上传纹理数据
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, atlasSurface->w, atlasSurface->h, 
                     0, format, GL_UNSIGNED_BYTE, atlasSurface->pixels);
        
        // 清理图集表面
        SDL_FreeSurface(atlasSurface);
        
        // 保存当前OpenGL状态
        GLboolean depthTestEnabled;
        glGetBooleanv(GL_DEPTH_TEST, &depthTestEnabled);
        
        // 启用混合
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        
        // 禁用深度测试写入，但保持深度测试
        glDepthMask(GL_FALSE);
        
        // 创建正交投影矩阵
        glm::mat4 orthoProjection = glm::ortho(
            0.0f, static_cast<float>(m_windowWidth),
            0.0f, static_cast<float>(m_windowHeight)
        );
        
        // 使用帮助文本的着色器程序
        glUseProgram(m_helpTextShaderProgram);
        
        // 设置投影矩阵
        GLint projLoc = glGetUniformLocation(m_helpTextShaderProgram, "projection");
        glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(orthoProjection));
        
        // 绑定纹理图集
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, m_labelTextureAtlas);
        GLint texLoc = glGetUniformLocation(m_helpTextShaderProgram, "textTexture");
        glUniform1i(texLoc, 0);
        
        // 为每个标签创建和渲染一个四边形
        for (size_t i = 0; i < m_gridLabels.size(); ++i)
        {
            if (i >= textureCoords.size() || textureCoords[i].z == 0) continue; // 跳过无效标签
            
            const auto& label = m_gridLabels[i];
            const auto& texCoord = textureCoords[i];
            
            // 将3D坐标转换为屏幕坐标
            glm::vec4 worldPos(label.x, label.y, label.z, 1.0f);
            glm::vec4 viewPos = m_viewMatrix * m_modelMatrix * worldPos;
            
            // 如果标注在相机后面，跳过
            if (viewPos.z > -0.1f) continue;
            
            // 进行视线检测 - 确保标注不在地球背面
            // 1. 获取相机位置在模型空间中的坐标
            glm::vec4 camPosWorld = glm::vec4(0.0f, 0.0f, m_zoom, 1.0f); // 相机位置在世界空间
            glm::vec4 camPosModel = glm::inverse(m_modelMatrix) * camPosWorld; // 转换到模型空间
            
            // 2. 计算从相机到标签点的方向
            glm::vec3 dirToCam = glm::normalize(glm::vec3(camPosModel) - glm::vec3(label.x, label.y, label.z));
            
            // 3. 计算标签点在球面上的法线方向（指向外部）
            glm::vec3 normalAtLabel = glm::normalize(glm::vec3(label.x, label.y, label.z));
            
            // 4. 通过点积判断标签是否面向相机
            float dotProduct = glm::dot(normalAtLabel, dirToCam);
            
            // 如果点积小于0，说明标签在地球背面，相机看不到
            if (dotProduct < 0.0f) continue;
            
            glm::vec4 clipPos = m_projectionMatrix * viewPos;
            
            // 执行透视除法
            float w = clipPos.w;
            glm::vec3 ndcPos = glm::vec3(clipPos) / w;
            
            // NDC坐标范围为[-1,1]，转换为屏幕坐标
            float screenX = (ndcPos.x + 1.0f) * 0.5f * m_windowWidth;
            float screenY = (ndcPos.y + 1.0f) * 0.5f * m_windowHeight;
            
            // 获取标签尺寸
            float padding = 4.0f; // 添加一些内边距
            float labelWidth = (texCoord.z - texCoord.x) * atlasWidth;
            float labelHeight = (texCoord.w - texCoord.y) * atlasHeight;
            
            // 计算屏幕上的四边形坐标
            float x = screenX - labelWidth * 0.5f - padding;
            float y = screenY - labelHeight * 0.5f - padding;
            float width = labelWidth + padding * 2.0f;
            float height = labelHeight + padding * 2.0f;
            
            // 创建顶点数据
            float vertices[] = {
                // 位置(x,y)       纹理坐标(s,t)
                x,         y + height, texCoord.x, texCoord.y,  // 左上
                x,         y,          texCoord.x, texCoord.w,  // 左下
                x + width, y,          texCoord.z, texCoord.w,  // 右下
                x + width, y + height, texCoord.z, texCoord.y   // 右上
            };
            
            // 创建索引
            unsigned int indices[] = {
                0, 1, 2,  // 第一个三角形
                0, 2, 3   // 第二个三角形
            };
            
            // 创建和绑定VAO和VBO
            GLuint textVAO, textVBO, textEBO;
            glGenVertexArrays(1, &textVAO);
            glGenBuffers(1, &textVBO);
            glGenBuffers(1, &textEBO);
            
            glBindVertexArray(textVAO);
            
            // 上传顶点数据
            glBindBuffer(GL_ARRAY_BUFFER, textVBO);
            glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
            
            // 上传索引数据
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, textEBO);
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
            
            // 设置顶点属性
            glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
            glEnableVertexAttribArray(0);
            glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
            glEnableVertexAttribArray(1);
            
            // 绘制文本
            glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
            
            // 清理资源
            glDeleteVertexArrays(1, &textVAO);
            glDeleteBuffers(1, &textVBO);
            glDeleteBuffers(1, &textEBO);
        }
        
        // 恢复OpenGL状态
        if (depthTestEnabled)
        {
            glDepthMask(GL_TRUE);
        }
        glDisable(GL_BLEND);
        glBindTexture(GL_TEXTURE_2D, 0);
        glUseProgram(0);
    }
}
_NNU_DGGS_END